package com.boco.blch.analysiser.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

public class PortRangeUtil {
	private static Properties pro = new Properties();
	private final static String PATH = "analysiser/port_range.properties";
	private final static String PREFIX = "port_range_";
	private static Logger logger = Logger.getLogger(PortRangeUtil.class);
	static{
		init();
	}
	
	private static void init(){
		InputStream in = PortRangeUtil.class.getClassLoader().getResourceAsStream(PATH);
		try {
			pro.load(in);
		} catch (IOException e) {
			logger.error(e + " 读取端口矩阵配置文件时发生错误，请确认文件是否存在！");
		}
	}
	
	private static String getKey(String name){
		return PREFIX + name.toLowerCase();
	}
	
	/**
	 * 判断待测端口号是否在端口矩阵中
	 * @param name 组件名称：hdfs,hive,flume,hbase,kafka,kerberos,mapreduce,spark,zookeeper
	 * @param port 待测端口号
	 * @return 
	 */
	public static boolean inRange(String name, int port){
		List<Integer> range = getRange(name);
		Object[] array = range.toArray();
		Arrays.sort(array);
		int index = Arrays.binarySearch(array, port);
		return index >= 0;
	}
	
	private static List<Integer> getRange(String name){
		String value = pro.getProperty(getKey(name));
		List<Integer> retVal = new ArrayList<Integer>();
		if(!StringUtils.isEmpty(value)){
			String[] sub = value.split(",");
			for(String port : sub){
				List<Integer> subList = exec(port);
				retVal.addAll(subList);
			}
		}
		
		return retVal;
	}
	
	/**
	 * 子解析，解析每个逗号之间的内容，如果是单个端口，就直接返回，如果是范围，就返回范围内的数值
	 * @param port
	 * @return
	 */
	private static List<Integer> exec(String port){
		List<Integer> retVal = new ArrayList<Integer>();
		try{
			if(port.indexOf("-") >= 0){
				String[] sub = port.split("-");
				int s = Integer.valueOf(sub[0]);
				int e = Integer.valueOf(sub[1]);
				int start = Math.min(s, e);
				int end = Math.max(s, e);
				for(int i = start; i <= end; i++){
					retVal.add(i);
				}
			} else {
				retVal.add(Integer.valueOf(port));
			}
		} catch (Exception e){
			logger.error(e + " 读取端口时发生错误，请确认格式是否正确！");
		}
		
		return retVal;
	}
	
	

}
